package wangjg.commons.dao;

import java.io.Serializable;
import java.util.List;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;

import wangjg.commons.bean.BeanUtil;

public abstract class AbstractBasicAO<T, ID extends Serializable>{

	private static final Pattern ppPattern = Pattern.compile("^[A-Z_a-z]\\w+$");
	
	protected void checkProperty(String property) {
		if(property==null){
			throw new NullPointerException();
		}
		java.util.regex.Matcher matcher = ppPattern.matcher(property);
		if(!matcher.matches()){
			throw new RuntimeException("非法的属性名!"+property);
		}
	}
	
	protected void update(final String entityName, String[] ppa, Object[] pva) {
		if(ppa.length==0){
			return;
		}
		StringBuilder sb = new StringBuilder();
		sb.append("update "+entityName);
		if(ppa.length>0){
			sb.append(" set ");
			sb.append(ppa[0]);
			sb.append("=?");
			for(int i=1;i<ppa.length;i++){
				String pp = ppa[i];
				sb.append(',');
				sb.append(pp);
				sb.append("=?");
			}
		}
		sb.append(" where");
		sb.append(" id=?");
		this.executeUpdate(sb.toString(), pva);
	}
	
	protected String getKInSql(String colName, List<Long> idList, int rangeSize){
		StringBuilder sqlsb = new StringBuilder();
		List<List<Long>> groupList = BeanUtil.splitList(idList, rangeSize);
		for(List<Long> group: groupList){
			sqlsb.append(" or "+colName+" in("+StringUtils.join(group, ',')+")");
		}
		if(sqlsb.length()>4){
			return sqlsb.substring(4);
		}else{
			return sqlsb.toString();
		}
	}

	public abstract ID save(final T entity);

	public abstract void update(final T entity);

	public abstract void saveOrUpdate(final T entity);

	public abstract void delete(final T entity);

	public abstract void delete(ID id);
	
	protected abstract List query(final String hql, final Object... values);

	protected abstract List query(int firstResult, int maxResults, final String hql, final Object... values);

	protected abstract Object queryUnique(final String hql, final Object... values);

	protected abstract int executeUpdate(final String hql, final Object... values);

	public abstract T findByProperty(String propertyName, Object value);

	public abstract <N extends Number> N findCountByProperty(String propertyName, Object propertyValue);

//	public abstract List<T> findListByProperty(String propertyName, Object propertyValue);

//	public abstract List<T> findListByProperty(String propertyName, Object propertyValue, String orderby, Boolean asc, Integer firstResult, Integer maxResults);

	public abstract List findPropertyList(String returnProperty, String fieldname, Object value);

//	public abstract List findPropertyList(String returnProperty, boolean distinct, String filterProperty, Object filterValue ,String orderby, Boolean asc, Integer firstResult, Integer maxResults);

	protected abstract T get(ID id);

	protected abstract T load(ID id);

	protected abstract void merge(final T entity);

//	protected abstract Query createQuery(final String queryString, final Object... values);

//	protected abstract Query createQuery(Session session, final String queryString, final Object...values);
	
}
